home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2000 #1 / Amiga Plus CD - 2000 - No. 1.iso / Tools / Dev / Sas-PPC / samplelib3 / libinit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-12-03  |  13.4 KB  |  467 lines

  1. #define  _USEOLDEXEC_ 1
  2. #include <exec/types.h>
  3. #include <exec/nodes.h>
  4. #include <exec/memory.h>
  5. #include <exec/resident.h>
  6. #include <exec/libraries.h>
  7. #include <exec/execbase.h>
  8. #include <libraries/dos.h>
  9. #include <proto/exec.h>
  10. #include <proto/dos.h>
  11. #include <string.h>
  12. #include <dos/dostags.h>
  13. #include <PowerUP/PPCLib/Interface.h>
  14. #include <PowerUP/PPCLib/tasks.h>
  15. #include <PowerUP/PPCLib/ppc.h>
  16. #include <PowerUP/PPCLib/object.h>
  17. #include <PowerUP/PPCDisslib/PPCDiss.h>
  18. #include <PowerUP/pragmas/ppc_pragmas.h>
  19. #include <PowerUP/clib/ppc_protos.h>
  20. #include <PowerUP/pragmas/ppcdiss_pragmas.h>
  21. #include <PowerUP/clib/ppcdiss_protos.h>
  22.  
  23.  
  24. /* Prototypes */
  25. ULONG __asm _LibExpunge( register __a6 struct MyLibrary *libbase );
  26. ULONG __asm _LibInit   ( register __a0 APTR seglist,
  27.                          register __d0 struct MyLibrary *libbase );
  28.  
  29. int  __saveds __asm __UserLibInit   (register __a6 struct MyLibrary *libbase);
  30. void __saveds __asm __UserLibCleanup(register __a6 struct MyLibrary *libbase);
  31.  
  32. int  __saveds __asm __UserDevInit   (register __d0 long unit,
  33.                                      register __a0 struct IORequest *ior,
  34.                                      register __a6 struct MyLibrary *libbase);
  35. void __saveds __asm __UserDevCleanup(register __a0 struct IORequest *ior,
  36.                                      register __a6 struct MyLibrary *libbase);
  37.  
  38. int  __saveds __asm __libfpinit     (register __a6 struct MyLibrary *libbase);
  39. void __saveds __asm __libfpterm     (register __a6 struct MyLibrary *libbase);
  40. void __saveds __asm Set_ElfEntry    (register __a6 struct MyLibrary *libbase, 
  41.                                      register __d0 long value);
  42.  
  43. struct MyLibrary {
  44.         struct             Library ml_Lib;
  45.         ULONG              ml_SegList;
  46.         ULONG              ml_Flags;
  47.         APTR               ml_ExecBase; /* pointer to exec base  */
  48. #ifndef ONE_GLOBAL_SECTION
  49.         long *             ml_relocs;   /* pointer to relocs.    */
  50.         struct MyLibrary * ml_origbase; /* pointer to original library base  */
  51.         long               ml_numjmps;
  52. #endif
  53.         void *             ml_MyObject; /* pointer to ELF Object */
  54.         long               ml_ElfEntry; /* Entrypoint of Elf stub */
  55.  
  56. };
  57.  
  58. typedef LONG (*myPFL)();   /* pointer to function returning 32-bit int      */
  59.  
  60. /* library initialization table, used for AUTOINIT libraries                */
  61. struct InitTable {
  62.         ULONG        *it_DataSize;       /* library data space size         */
  63.         myPFL        *it_FuncTable;      /* table of entry points           */
  64.         APTR         it_DataInit;        /* table of data initializers      */
  65.         myPFL        it_InitFunc;        /* initialization function to run  */
  66. };
  67.  
  68. #ifndef ONE_GLOBAL_SECTION
  69. long _OSERR;
  70. long __base;
  71. #endif
  72.  
  73. /* symbols generated by blink */
  74. extern char __far _LibID[];             /* ID string                        */
  75. extern char __far _LibName[];           /* Name string                      */
  76. extern char __far RESLEN;               /* size of init data                */
  77. extern long __far NEWDATAL;             /* size of global data              */
  78. extern long __far NUMJMPS;              /* number of jmp vectors to copy    */
  79. extern myPFL _LibFuncTab[];             /* my function table                */
  80. extern long __far _LibVersion;          /* Version of library               */
  81. extern long __far _LibRevision;         /* Revision of library              */
  82.  
  83. long _StackPtr;
  84. long __stack;
  85. long __base;
  86. long _ONEXIT;
  87. struct WBStartup *_WBenchMsg;
  88. struct WBStartup *WBenchMsg;
  89.  
  90.  
  91. #define MYVERSION ((long)&_LibVersion)
  92. #define MYREVISION ((long)&_LibRevision)
  93. #define DATAWORDS ((long)&NEWDATAL)     /* magic to get right tpye of reloc */ 
  94. #define SIZEJMPTAB ((((long)libbase->ml_origbase->ml_numjmps)+3)&~3)
  95.                                         /* size in bytes of jmp table       */
  96.  
  97. /* From libent.o, needed to determine where data is loaded by loadseg       */
  98. extern long far _Libmergeddata; 
  99.  
  100. #define MYLIBRARYSIZE ((sizeof(struct MyLibrary) +3) & ~3)
  101.  
  102.  
  103.  
  104. struct InitTable __far _LibInitTab =  {
  105.         (long *)(&RESLEN+MYLIBRARYSIZE),
  106.         _LibFuncTab,
  107.         NULL,                        /* will initialize my own data */
  108.         _LibInit,
  109. };
  110.  
  111.  
  112. int _chkabort(void)
  113. {
  114.     return 0;
  115. }
  116.  
  117.  
  118.  
  119. int CreatePPCTask(struct MyLibrary *libbase, void *entry)
  120. {
  121.     struct TagItem    MyTags[13];
  122.     struct DOSLibrary *DOSBase;
  123.     struct Library *PPCLibBase;
  124.     long result;
  125.     
  126.     DOSBase = (void *)OpenLibrary("dos.library", 0);
  127.     if (DOSBase == NULL) return -1;
  128.  
  129.     if ((PPCLibBase = OpenLibrary("ppc.library",0)) == NULL)
  130.     {
  131.         CloseLibrary((void *)DOSBase);
  132.         return -1;
  133.     }
  134.  
  135.     MyTags[0].ti_Tag    =    PPCTASKTAG_STOPTASK;
  136.     MyTags[0].ti_Data    =    FALSE;
  137.     MyTags[1].ti_Tag    =    PPCTASKTAG_WAITFINISH;
  138.     MyTags[1].ti_Data    =    TRUE;
  139.     MyTags[2].ti_Tag    =    PPCTASKTAG_INPUTHANDLE;
  140.     MyTags[2].ti_Data    =    (ULONG) Input();
  141.     MyTags[3].ti_Tag    =    PPCTASKTAG_OUTPUTHANDLE;
  142.     MyTags[3].ti_Data    =    (ULONG) Output();
  143.     MyTags[4].ti_Tag    =    PPCTASKTAG_ARG1;
  144.     MyTags[4].ti_Data    =    (ULONG) 0;
  145.     MyTags[5].ti_Tag    =    PPCTASKTAG_STACKSIZE;
  146.     MyTags[5].ti_Data    =    0x10000;
  147.     MyTags[6].ti_Tag    =    NP_CloseInput;
  148.     MyTags[6].ti_Data    =    FALSE;
  149.     MyTags[7].ti_Tag    =    NP_CloseOutput;
  150.     MyTags[7].ti_Data    =    FALSE;
  151.     MyTags[8].ti_Tag    =    PPCTASKTAG_BREAKSIGNAL;
  152.     MyTags[8].ti_Data    =    TRUE;
  153.     MyTags[9].ti_Tag    =    PPCTASKTAG_ARG3;
  154.     MyTags[9].ti_Data    =    (ULONG) libbase;
  155.     MyTags[10].ti_Tag    =    PPCTASKTAG_ARG4;
  156.     MyTags[10].ti_Data    =    (ULONG) entry;
  157.     MyTags[11].ti_Tag    =    PPCTASKTAG_ARG2;
  158.     MyTags[11].ti_Data    =    (ULONG) _WBenchMsg;
  159.  
  160.     MyTags[12].ti_Tag    =    TAG_END;
  161.  
  162.     CloseLibrary((void *)DOSBase);
  163.  
  164.     result =  (ULONG) PPCCreateTask(libbase->ml_MyObject,
  165.                                     &MyTags[0]);
  166.                                      
  167.     CloseLibrary(PPCLibBase);
  168.     return result; 
  169.  
  170. }
  171.  
  172. /* PPC functions that run the PPC autoinitializers */
  173. extern int __far _fpinit(void);
  174. extern int __far _fpterm(void);
  175.  
  176. int  __saveds __asm __libfpinit(register __a6 struct MyLibrary *libbase)
  177. {
  178.     return CreatePPCTask(libbase, _fpinit);
  179. }
  180.  
  181. void __saveds __asm __libfpterm(register __a6 struct MyLibrary *libbase)
  182. {
  183.     CreatePPCTask(libbase, _fpterm);
  184. }
  185.  
  186.  
  187.  
  188. __asm ULONG _LibInit( register __a0 APTR seglist,
  189.                       register __d0 struct MyLibrary *libbase )
  190. {
  191. #ifdef ONE_GLOBAL_SECTION
  192.     long *reloc;
  193. #endif
  194.     long *sdata;
  195.     char *ddata;
  196.     long nrelocs;
  197.     struct TagItem MyTags[3];
  198.     extern __far long _ElfObject;
  199.     struct Library *PPCLibBase;
  200.  
  201.     libbase->ml_SegList = (ULONG) seglist;
  202.  
  203.     /* init. library structure (since I don't do automatic data init.) */
  204. #ifdef DEVICE
  205.     libbase->ml_Lib.lib_Node.ln_Type = NT_DEVICE;
  206. #else
  207.     libbase->ml_Lib.lib_Node.ln_Type = NT_LIBRARY;
  208. #endif
  209.     libbase->ml_Lib.lib_Node.ln_Name =  _LibName;
  210.     libbase->ml_Lib.lib_Flags = LIBF_SUMUSED | LIBF_CHANGED;
  211.     libbase->ml_Lib.lib_Version = MYVERSION;
  212.     libbase->ml_Lib.lib_Revision = MYREVISION;
  213.     libbase->ml_Lib.lib_IdString = (APTR) _LibID;
  214. #ifndef ONE_GLOBAL_SECTION
  215.     libbase->ml_relocs = NULL;
  216.     libbase->ml_origbase = libbase;
  217.     sdata = (long *)_LibInitTab.it_FuncTable;
  218.     libbase->ml_numjmps = (long)&NUMJMPS;
  219. #endif
  220.  
  221.     /* load the PPC ELF stub */
  222.     MyTags[0].ti_Tag = PPCELFLOADTAG_ELFADDRESS;
  223.     MyTags[0].ti_Data = (long)&_ElfObject;
  224.     MyTags[1].ti_Tag = PPCELFLOADTAG_ELFNAME;
  225.     MyTags[1].ti_Data = (long)_LibName;
  226.     MyTags[2].ti_Tag = TAG_DONE;
  227.  
  228.  
  229.     if ((PPCLibBase = OpenLibrary("ppc.library",0)) == NULL)
  230.        return NULL;
  231.  
  232.     if (libbase->ml_MyObject=PPCLoadObjectTagList(MyTags))
  233.     {
  234.         struct PPCObjectInfo MyInfo;
  235.  
  236.         MyInfo.Address   =        0;
  237.         MyInfo.Name      =        "__Entry";
  238.         MyTags[0].ti_Tag =        TAG_END;
  239.  
  240.         PPCGetObjectAttrs(libbase->ml_MyObject,
  241.                           &MyInfo,
  242.                           MyTags);
  243.         libbase->ml_ElfEntry = MyInfo.Address;
  244.         Set_ElfEntry(libbase, MyInfo.Address);
  245.         
  246.     }
  247.     else
  248.     {
  249.        CloseLibrary(PPCLibBase);
  250.        return NULL;
  251.     }
  252.     CloseLibrary(PPCLibBase);
  253.  
  254.  
  255.      /* Start of copy of global data after structure */
  256.     ddata = (char *)libbase + MYLIBRARYSIZE; 
  257.  
  258.     sdata = (long *)&_Libmergeddata; /* where loadseg loaded the data */
  259.     memcpy(ddata, (void *)sdata, DATAWORDS*4);
  260.  
  261.     /* perform relocs if we want one global section for all programs */
  262.     /* that have this lib open. If we want a global section for each */
  263.     /* open, copy the relocs, and do them on each open call.         */
  264.     sdata = sdata + DATAWORDS;
  265.     nrelocs = *sdata;
  266. #ifdef ONE_GLOBAL_SECTION
  267.     sdata++;
  268.     while (nrelocs > 0)
  269.     {
  270.        reloc = (long *)((long)ddata + *sdata++);
  271.        *reloc += (long)ddata;
  272.        nrelocs--;
  273.     }
  274.     
  275.     
  276. #ifndef DEVICE
  277.     if (__UserLibInit(libbase) != 0)
  278.        return NULL; /* abort if user init failed */
  279. #endif
  280.  
  281. #else
  282.     if (nrelocs) 
  283.     {
  284.       if ((libbase->ml_relocs = AllocMem((nrelocs * 4) + 4, MEMF_PUBLIC)) == NULL)
  285.         return 0;
  286.       memcpy((void *)libbase->ml_relocs, (void *)sdata, (nrelocs * 4) + 4);
  287.     }
  288. #endif
  289.  
  290.     return ( (ULONG) libbase );
  291. }
  292.  
  293. LONG __asm _LibOpen( 
  294. #ifdef DEVICE
  295.                      register __d0 long unit,
  296.                      register __a1 struct IORequest *ior,
  297. #endif
  298.                      register __a6 struct MyLibrary *libbase )
  299. {
  300. #ifndef ONE_GLOBAL_SECTION
  301.     struct MyLibrary *origbase = libbase;
  302.     struct ExecBase *SysBase = *(struct ExecBase **)4;
  303.     char *newlib;
  304.     long *sdata, *ddata, *reloc;
  305.     long nrelocs;
  306. #endif
  307.  
  308.     /* mark us as having another customer */
  309.     libbase->ml_Lib.lib_OpenCnt++;
  310.  
  311.     /* clear delayed expunges (standard procedure) */
  312.     libbase->ml_Lib.lib_Flags &= ~LIBF_DELEXP;
  313.  
  314. #ifndef ONE_GLOBAL_SECTION
  315.     /* Allocate new lib base */
  316.     newlib = AllocMem((long)(MYLIBRARYSIZE + 
  317.                              ((long)&RESLEN) + SIZEJMPTAB), 
  318.                              MEMF_PUBLIC|MEMF_CLEAR);
  319.  
  320.     if (newlib == NULL) goto error;
  321.         
  322.     /* copy over data */
  323.     memcpy(newlib, (char *)libbase - SIZEJMPTAB, 
  324.            (long)(MYLIBRARYSIZE + DATAWORDS*4 + SIZEJMPTAB));
  325.     
  326.     libbase = (struct MyLibrary *)(newlib+SIZEJMPTAB);
  327.     libbase->ml_relocs = NULL;
  328.     
  329.     /* perform relocs */       
  330.     ddata = (long *)((char *)libbase + MYLIBRARYSIZE); 
  331.     sdata = libbase->ml_origbase->ml_relocs;
  332.     if (sdata)
  333.     {
  334.        nrelocs = *sdata++;
  335.        while (nrelocs > 0)
  336.        {
  337.           reloc = (long *)((long)ddata + *sdata++);
  338.           *reloc += (long)ddata;
  339.           nrelocs--;
  340.        }
  341.     }
  342.  
  343.  
  344.     Set_ElfEntry(libbase, libbase->ml_ElfEntry);
  345.         
  346.  
  347.     /* now we need to flush the cache because we copied the jmp table */
  348.     if (SysBase->LibNode.lib_Version >= 36) 
  349.       CacheClearU();
  350.  
  351. #ifdef DEVICE
  352.     ior->io_Device = (struct Device *)libbase; /* local copy of libary base */
  353. #endif
  354.  
  355.     if (__libfpinit(libbase) || 
  356. #ifdef DEVICE
  357.         __UserDevInit(unit, ior, libbase) != 0
  358. #else
  359.         __UserLibInit(libbase) != 0
  360. #endif
  361.        )
  362.     {
  363.        __libfpterm(libbase);
  364.        FreeMem(newlib, (long)(MYLIBRARYSIZE + 
  365.                        ((long)&RESLEN) + SIZEJMPTAB));
  366. error:
  367.        origbase->ml_origbase->ml_Lib.lib_OpenCnt--;
  368.        return NULL; /* abort if user init failed */
  369.     }
  370.  
  371. #else
  372. #ifdef DEVICE
  373.     if (__UserDevInit(unit, ior, libbase) != 0)
  374.     {
  375.         libbase->ml_Lib.lib_OpenCnt--;
  376.         return NULL;
  377.     }    
  378. #endif
  379. #endif
  380.  
  381.     return ( (LONG) libbase );
  382. }
  383.  
  384. ULONG __asm _LibClose( 
  385. #ifdef DEVICE
  386.                        register __a1 struct IORequest *ior,
  387. #endif                       
  388.                        register __a6 struct MyLibrary *libbase )
  389. {
  390.     ULONG retval = 0;
  391.     
  392. #ifndef ONE_GLOBAL_SECTION
  393.     struct MyLibrary *origbase;
  394.  
  395.     if (libbase != libbase->ml_origbase)
  396.     {
  397. #ifdef DEVICE
  398.        __UserDevCleanup(ior, libbase);
  399. #else
  400.        __UserLibCleanup(libbase);
  401. #endif
  402.        __libfpterm(libbase);
  403.  
  404.        origbase = libbase->ml_origbase;
  405.        FreeMem((char *)libbase-SIZEJMPTAB, 
  406.                (long)(MYLIBRARYSIZE + ((long)&RESLEN)+SIZEJMPTAB));
  407.        libbase = origbase;
  408.     }
  409. #else
  410. #ifdef DEVICE
  411.     __UserDevCleanup(ior, libbase);
  412. #endif
  413. #endif
  414.  
  415.     if (( --libbase->ml_Lib.lib_OpenCnt == 0 ) &&
  416.                         ( libbase->ml_Lib.lib_Flags & LIBF_DELEXP ))
  417.     {
  418.         /* no more people have me open,
  419.          * and I have a delayed expunge pending
  420.          */
  421.          retval = _LibExpunge( libbase ); /* return segment list        */
  422.     }
  423.  
  424.     return (retval);
  425. }
  426.  
  427. ULONG __asm _LibExpunge( register __a6 struct MyLibrary *libbase )
  428. {
  429.     ULONG seglist = 0;
  430.     LONG  libsize;
  431.     struct Library *PPCLibBase;
  432.  
  433. #ifndef ONE_GLOBAL_SECTION
  434.     libbase = libbase->ml_origbase;
  435. #endif
  436.  
  437.     libbase->ml_Lib.lib_Flags |= LIBF_DELEXP;
  438.     if ( libbase->ml_Lib.lib_OpenCnt == 0 )
  439.     {
  440.         /* really expunge: remove libbase and freemem        */
  441. #ifndef ONE_GLOBAL_SECTION
  442.         if (libbase->ml_relocs)
  443.            FreeMem(libbase->ml_relocs, (*libbase->ml_relocs * 4) + 4);
  444. #else
  445.         __UserLibCleanup(libbase);
  446. #endif
  447.  
  448.         if (PPCLibBase = OpenLibrary("ppc.library",0))
  449.         {
  450.            PPCUnLoadObject(libbase->ml_MyObject);
  451.            CloseLibrary(PPCLibBase);
  452.         }
  453.         
  454.         seglist = libbase->ml_SegList;
  455.  
  456.         Remove( (struct Node *) libbase);
  457.  
  458.         libsize = libbase->ml_Lib.lib_NegSize + libbase->ml_Lib.lib_PosSize;
  459.         FreeMem( (char *) libbase - libbase->ml_Lib.lib_NegSize,(LONG) libsize );
  460.     }
  461.  
  462.     /* return NULL or real seglist                                */
  463.     return ( (ULONG) seglist );
  464. }
  465.  
  466.  
  467.